home *** CD-ROM | disk | FTP | other *** search
- TEXT SEGMENT PUBLIC WORD 'CODE'
-
-
- ASSUME CS:TEXT,DS:TEXT,ES:TEXT,SS:TEXT
-
- ; Magic constants. These are for WD controller, version x.xx.
- WDC_SEG EQU 0C800h ; Segment for WD ROM BIOS.
- WDC_SIZ EQU 0800h ; Size, in bytes, of WD ROM BIOS.
-
-
-
- ; This program will relocate the Western Digital Controller
- ; ROM BIOS code into RAM. If you are fortunate enough to own an
- ; AT&T PC6300, this will do wonders for you disk speeds.
- ;
- ; While the AT&T has a 16 bit processor with 16 bit RAM and ROM,
- ; whenever it tries to run the ROM BIOS on the WDC card, all that
- ; power is wasted trying to read 16 bit instructions off the 8 bit
- ; I/O bus. The bus converter board 'works', but it take much longer
- ; than necessary.
- ;
- ; By relocating the WD code to RAM, we stay away from the bus converter
- ; and its wasteful overhead. Consequently, you can reformat the
- ; hard disk to an interleave of 4!!. The best one can normally do
- ; with the AT&T 6300 is 6. This would appear to be a 50% improvement.
- ;
- ; Since I have only one controller to test it on, I tried to avoid the
- ; usual practice of hardcoding constants. Instead, I look for
- ; the two instructions which will take over the BIOS ints. From these
- ; MOV instructions, I get the address of WD's INT handler. Then I
- ; search DOS to see where it has saved those addresses when it proceeded
- ; to steal those vectors for itself.
- ;
- ; There are obvious risks with inadvertantly clobbering DOS, but things
- ; seem to work for both DOS 3.1 and DOS 3.3.
- ;
- ; Naturally, I will disclaim any and everything. Still, let me know
- ; if you have any problems, or your version of the WDC has instructions
- ; other than those I am skipping over. Just DEBUG and disassemble
- ; from C800:0003 and follow the JMP.
- ;
- ; Copyright (c) 1987, Hanover Systems, All Rights Reserved.
- ;
- ;
- ; Good luck, Chris Smith, Newtown, CT 203-426-0024.
- ;
-
-
- RAMC800 PROC FAR
-
- ; OK, Let's reserve room for this mess...
- NEWROM:
- PUSH DS
- PUSH ES
- JMP LOADER
- DB WDC_SIZ dup (?)
-
- ; Private data area.
- VEC4C DW -1 ; Offset for INT 13 entry.
- VEC64 DW -1 ; Offset for INT 25 entry.
- VECS DB 0 ; Number vectors found so far.
-
- ; Now, let's copy the ROM stuff from C800:0000 to NEWROM
- LOADER:
- MOV AX,WDC_SEG
- MOV ES,AX
- MOV AX,CS
- MOV DS,AX
- MOV SI,0
- LEA DI,NEWROM
- MOV CX,WDC_SIZ/2
-
- COPYROM:
- MOV AX,ES:[SI]
- MOV [DI],AX
- ADD SI,2
- ADD DI,2
- LOOP COPYROM
-
- ; Try to find our two magic constants...
- ; We need the addresses stuffed to locations 4C and 64.
-
- ; Find where init code starts...
- CMP byte ptr NEWROM+3,0EBh ; This a short jump?
- JNE BADROM ; No, give up right here.
- MOV AL,byte ptr [NEWROM+4] ; Yes, get offset.
- CBW ; Use fullword.
- ADD AX,5 ; Get address init code.
-
- ; Skip over unnecessary instructions.
- MOV VECS,0 ; Start with nothing on record.
- MOV CX,100 ; Don't go on forever.
- MOV SI,AX
- CLD
- DECODE:
- CMP word ptr [SI],0C033h ; "XOR AX,AX"?
- JE DEC2 ; Yes, skip two bytes.
- CMP word ptr [SI],0D88Eh ; "MOV DS,AX"?
- JE DEC2 ; Yes, skip two bytes.
- CMP byte ptr [SI],0FAh ; "CLI"?
- JE DEC1 ; Yes, skip it.
- CMP word ptr [SI],006C4h ; "LES AX,constant"?
- JE DEC4 ; Yes, skip four bytes.
- CMP word ptr [SI],000A3h ; "MOV vector,AX"?
- JE DEC3 ; Yes, skip it.
- CMP word ptr [SI],0068Ch ; "MOV vector,ES"?
- JE DEC4 ; Yes, skip it.
- CMP word ptr [SI],00E8Ch ; "MOV vector,CS"?
- JE DEC4 ; Yes, skip it.
- CMP word ptr [SI],006C7h ; "MOV vector, constant"?
- JNE BADROM ; No, I don't know what to do!!!
-
- ; We have a constant move into a vector. See if vector is 4C or 64.
- ADD SI,2 ; Advance to vector address.
- CMP word ptr [SI],00064h ; To vector at 64?
- JE FOUND64 ; Yes, now we're making progress.
- CMP word ptr [SI],0004Ch ; To vector at 4C?
- JNE DEC4 ; Knock 4 more bytes off this instruction.
-
- ; We found the MOV instruction that sets up vector at 4C.
- MOV AX,word ptr [SI+2] ; Get code entry.
- MOV VEC4C,AX ; Save for later.
- INC VECS ; We found one vector.
- JMP DEC4 ; Go look for more, if necessary.
-
- ; We found the MOV instruciton that sets up vector at 64.
- FOUND64:
- MOV AX,word ptr [SI+2] ; Get code entry.
- MOV VEC64,AX ; Save for later.
- INC VECS ; We found one vector.
-
- ; Advance to next instruction.
- DEC4: INC SI
- DEC3: INC SI
- DEC2: INC SI
- DEC1: INC SI
- CMP byte ptr VECS,2 ; We get both vectors yet?
- JE FIXDOS ; Yes, now go patch DOS.
- LOOP DECODE ; No, keep going for a bit.
-
- ; We weren't able to find our addresses. Abort.
- BADROM:
- LEA DX,BADROMMSG
- MOV AH,9 ; Print string function.
- INT 21H ; Do it.
-
- POP ES
- POP DS
- XOR AX,AX ; Terminate.
- INT 21H
-
-
- BADROMMSG DB "Undecodable WD controller BIOS.",0AH,0DH,'$'
-
-
-
- ; Naturally, somebody whose name we won't mention has stolen our
- ; vectors... Find where that nasty Redmont Wa company has stuffed
- ; them & re-direct them to our RAM based code...
-
- ; First, find where the original 4C vector went...
- FIXDOS:
- MOV AX,VEC4C ; Search for C800:V_VEC4C
- XOR BX,BX ; Start at 0:0
- S4C: CALL FINDIT
- JC FIND64
- MOV word ptr ES:[BX],CS ; Use RAM version instead.
- JMP S4C ; Look for at least one more instance.
-
- ; Then, find where the original 64 vector went...
- FIND64: MOV AX,VEC64 ; Search for C800:V_VEC64
- XOR BX,BX ; Start at 0:0
- S64: CALL FINDIT
- JC FIXDMA
- MOV word ptr ES:[BX],CS ; Use RAM version instead.
- JMP S64 ; Just in case there are any more...
-
- ; We've patched DOS to go to our RAM copy of WD code.
- FIXDMA:
- ; If I were going to screw around with the DMA programming, I'd
- ; put my patches here. So far, nothing seems to help.
-
-
- ; Now, do a TSR number, leaving the ROM stuff here.
- LEA DX,ALLDONEMSG
- MOV AH,9 ; Print string function.
- INT 21H ; Do it.
-
- MOV AX,3100H
- MOV DX,800H/10H ; Get amount to remain resident.
- POP ES
- POP DS
- INT 21H
-
- ALLDONEMSG DB "WD BIOS moved to RAM.",0AH,0DH
- DB "Hanover Systems, (c) 1987",0AH,0AH,0DH,'$'
-
- RAMC800 ENDP
-
-
-
- ; Subroutine to scan memory for patchable address inside DOS.
- ; AX=value to match, (Don't forget C800: follows). BX is offset
- ; to start with. Set C flag if we don't find anything between offset
- ; 0 and FFFE.
-
- FINDIT PROC NEAR
- XOR DX,DX
- MOV ES,DX
- FINDL1: CMP byte ptr ES:[BX],AL
- JNE FINDL2 ; Didn't match offset.
- CMP byte ptr ES:[BX+1],AH
- JNE FINDL2
- CMP word ptr ES:[BX+2],WDC_SEG
- JE FINDL3 ; We matched segment!!
- FINDL2: ADD BX,1
- JNZ FINDL1
- STC ; Indicate not found.
- RET
-
- FINDL3: ADD BX,2 ; Point at segment.
- CLC ; Indicate we found our man.
- RET
-
- FINDIT ENDP
-
- TEXT ENDS
-
- END
-
-
-
-
-
-
-
-
-
-
-
-